1 module hip.event.handlers.mouse;
2 public import hip.api.input.mouse;
3 import hip.math.vector;
4 import hip.event.handlers.button;
5 import hip.error.handler;
6 import hip.util.data_structures;
7 import hip.util.reflection;
8 
9 class HipMouse
10 {
11     Vector2[] positions;
12     Vector2[] lastPositions;
13     Vector3 scroll;
14     HipButtonMetadata[enumLength!HipMouseButton] metadatas;
15 
16     this()
17     {
18         positions = new Vector2[](1); //Start it with at least 1
19         lastPositions = new Vector2[](1); //Start it with at least 1
20         positions[0] = Vector2(0,0);
21         lastPositions[0] = Vector2(0,0);
22         foreach(i; 0..enumLength!HipMouseButton)
23             metadatas[i] = new HipButtonMetadata(cast(int)i);
24     }
25 
26     void setPressed(HipMouseButton btn, bool pressed)
27     {
28         metadatas[cast(int)btn].setPressed(pressed);
29     }
30 
31     bool isPressed(HipMouseButton btn = HipMouseButton.any)
32     {
33         if(btn == HipMouseButton.any)
34         {
35             foreach(b; __traits(allMembers, HipMouseButton))
36             {
37                 HipMouseButton mem = __traits(getMember, HipMouseButton, b);
38                 if(mem >= HipMouseButton.any)
39                     return false;
40                 if(metadatas[mem].isPressed)
41                     return true;
42             }
43             return false;
44         }
45         return metadatas[btn].isPressed;
46     }
47 
48     bool isJustPressed(HipMouseButton btn)
49     {
50         if(btn == HipMouseButton.any)
51         {
52             foreach(b; __traits(allMembers, HipMouseButton))
53             {
54                 HipMouseButton mem = __traits(getMember, HipMouseButton, b);
55                 if(mem >= HipMouseButton.any)
56                     return false;
57                 if(metadatas[mem].isJustPressed)
58                     return true;
59             }
60             return false;
61         }
62         return metadatas[btn].isJustPressed;
63     }
64     bool isJustReleased(HipMouseButton btn)
65     {
66         if(btn == HipMouseButton.any)
67         {
68             foreach(b; __traits(allMembers, HipMouseButton))
69             {
70                 HipMouseButton mem = __traits(getMember, HipMouseButton, b);
71                 if(mem >= HipMouseButton.any)
72                     return false;
73                 if(metadatas[mem].isJustReleased)
74                     return true;
75             }
76             return false;
77         }
78         return metadatas[btn].isJustReleased;
79     }
80     void setPosition(float x, float y, uint id = 0)
81     {
82         if(id+1 > positions.length)
83             positions.length = id+1;
84         if(id+1 > lastPositions.length)
85         {
86             lastPositions.length = id+1;
87         }
88         lastPositions[id] = positions[id];
89         ErrorHandler.assertExit(id < positions.length, "Touch ID out of range");
90         positions[id].x=x;
91         positions[id].y=y;
92     }
93 
94     HipButtonMetadata getMetadata(HipMouseButton btn = HipMouseButton.any)
95     {
96         if(btn == HipMouseButton.any)
97             btn = HipMouseButton.left;
98         return metadatas[btn];
99     }
100     void setScroll(float x, float y, float z)
101     {
102         scroll.x=x;
103         scroll.y=y;
104         scroll.z=z;
105     }
106     
107 
108     ///Use the ID for getting the touch, may return null
109     Vector2 getPosition(uint id = 0)
110     {
111         if(id > positions.length) return Vector2.zero;
112         return positions[id];
113     }
114     Vector2 getDeltaPosition(uint id = 0)
115     {
116         if(id > positions.length) return Vector2.zero;
117 
118         return positions[id] - lastPositions[id];
119     }
120     Vector3 getScroll(){return scroll;}
121     ubyte getMulticlickCount(HipMouseButton btn = HipMouseButton.left)
122     {
123         import hip.error.handler;
124         if(btn == HipMouseButton.any)
125             ErrorHandler.showWarningMessage("getMulticlickCount", "Can't get multiclick count for any button.");
126         return metadatas[btn].clickCount;
127     }
128 
129     bool isDoubleClicked(HipMouseButton btn = HipMouseButton.left)
130     {
131         if(btn == HipMouseButton.any)
132         {
133             foreach(b; __traits(allMembers, HipMouseButton))
134             {
135                 HipMouseButton mem = __traits(getMember, HipMouseButton, b);
136                 if(mem >= HipMouseButton.any)
137                     return false;
138                 if(metadatas[mem].clickCount == 2 && metadatas[mem]._isNewState)
139                     return true;
140             }
141             return false;
142         }
143         return metadatas[btn].clickCount == 2 && metadatas[btn]._isNewState;
144     }
145 
146     void postUpdate()
147     {
148         for(int i = 0; i < metadatas.length; i++)
149             metadatas[i]._isNewState = false;
150         for(int i = 0; i < lastPositions.length; i++)
151             lastPositions[i] = positions[i];
152         setScroll(0,0,0);
153     }
154 }